From: kaf24@firebug.cl.cam.ac.uk Date: Mon, 12 Jun 2006 08:45:03 +0000 (+0100) Subject: [HVM][VMX] Provide right view of cpuid to the HVM guests. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15972^2~13 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=efeb20bcb522474f797c9bd9fd0f7ef049ba3055;p=xen.git [HVM][VMX] Provide right view of cpuid to the HVM guests. Some of the CPU features such as APIC, PAE, MTRR, HT are virtualized; while others are not virtualized yet such as TM1, TM2, MCA and there are some features which do not need virtualization such as MMX. With the patch Guest sees only those processor features in the cpuid which are virtualized in the hyper visor, or do not need any virtualization in hypervisor. Signed-off-by: Nitin A Kamble Signed-off-by: Jun Nakajima Signed-off-by: Asit Mallick --- diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 70f291a27f..2b5d0eb536 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #if CONFIG_PAGING_LEVELS >= 3 #include @@ -749,9 +750,7 @@ static void vmx_do_no_device_fault(void) } } -/* Reserved bits: [31:15], [12:11], [9], [6], [2:1] */ -#define VMX_VCPU_CPUID_L1_RESERVED 0xffff9a46 - +#define bitmaskof(idx) (1U << ((idx)&31)) static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs) { unsigned int input = (unsigned int)regs->eax; @@ -768,50 +767,74 @@ static void vmx_vmexit_do_cpuid(struct cpu_user_regs *regs) (unsigned long)regs->ecx, (unsigned long)regs->edx, (unsigned long)regs->esi, (unsigned long)regs->edi); - if ( input == 4 ) + if ( input == CPUID_LEAF_0x4 ) + { cpuid_count(input, count, &eax, &ebx, &ecx, &edx); + eax &= NUM_CORES_RESET_MASK; + } else + { cpuid(input, &eax, &ebx, &ecx, &edx); - if ( input == 1 ) - { - if ( !hvm_apic_support(v->domain) || - !vlapic_global_enabled((VLAPIC(v))) ) + if ( input == CPUID_LEAF_0x1 ) { - clear_bit(X86_FEATURE_APIC, &edx); - /* Since the apic is disabled, avoid any confusion about SMP cpus being available */ - clear_bit(X86_FEATURE_HT, &edx); /* clear the hyperthread bit */ - ebx &= 0xFF00FFFF; /* set the logical processor count to 1 */ - ebx |= 0x00010000; - } + /* mask off reserved bits */ + ecx &= ~VMX_VCPU_CPUID_L1_ECX_RESERVED; + if ( !hvm_apic_support(v->domain) || + !vlapic_global_enabled((VLAPIC(v))) ) + { + /* Since the apic is disabled, avoid any + confusion about SMP cpus being available */ + clear_bit(X86_FEATURE_APIC, &edx); + } + #if CONFIG_PAGING_LEVELS < 3 - clear_bit(X86_FEATURE_PAE, &edx); - clear_bit(X86_FEATURE_PSE, &edx); - clear_bit(X86_FEATURE_PSE36, &edx); + edx &= ~(bitmaskof(X86_FEATURE_PAE) | + bitmaskof(X86_FEATURE_PSE) | + bitmaskof(X86_FEATURE_PSE36)); #else - if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 ) - { - if ( !v->domain->arch.hvm_domain.pae_enabled ) - clear_bit(X86_FEATURE_PAE, &edx); - clear_bit(X86_FEATURE_PSE, &edx); - clear_bit(X86_FEATURE_PSE36, &edx); - } + if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 ) + { + if ( !v->domain->arch.hvm_domain.pae_enabled ) + clear_bit(X86_FEATURE_PAE, &edx); + clear_bit(X86_FEATURE_PSE, &edx); + clear_bit(X86_FEATURE_PSE36, &edx); + } #endif - /* Unsupportable for virtualised CPUs. */ - ecx &= ~VMX_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */ - clear_bit(X86_FEATURE_VMXE & 31, &ecx); - clear_bit(X86_FEATURE_MWAIT & 31, &ecx); - } + ebx &= NUM_THREADS_RESET_MASK; + + /* Unsupportable for virtualised CPUs. */ + ecx &= ~(bitmaskof(X86_FEATURE_VMXE) | + bitmaskof(X86_FEATURE_EST) | + bitmaskof(X86_FEATURE_TM2) | + bitmaskof(X86_FEATURE_CID) | + bitmaskof(X86_FEATURE_MWAIT) ); + + edx &= ~( bitmaskof(X86_FEATURE_HT) | + bitmaskof(X86_FEATURE_MCA) | + bitmaskof(X86_FEATURE_MCE) | + bitmaskof(X86_FEATURE_ACPI) | + bitmaskof(X86_FEATURE_ACC) ); + } + else if ( ( input == CPUID_LEAF_0x6 ) + || ( input == CPUID_LEAF_0x9 ) + || ( input == CPUID_LEAF_0xA )) + { + eax = ebx = ecx = edx = 0x0; + } #ifdef __i386__ - else if ( input == 0x80000001 ) - { - /* Mask feature for Intel ia32e or AMD long mode. */ - clear_bit(X86_FEATURE_LM & 31, &edx); - } + else if ( input == CPUID_LEAF_0x80000001 ) + { + clear_bit(X86_FEATURE_LAHF_LM & 31, &ecx); + + clear_bit(X86_FEATURE_LM & 31, &edx); + clear_bit(X86_FEATURE_SYSCALL & 31, &edx); + } #endif + } regs->eax = (unsigned long) eax; regs->ebx = (unsigned long) ebx; diff --git a/xen/include/asm-x86/hvm/vmx/cpu.h b/xen/include/asm-x86/hvm/vmx/cpu.h index 40161b7231..8c214ae1ce 100644 --- a/xen/include/asm-x86/hvm/vmx/cpu.h +++ b/xen/include/asm-x86/hvm/vmx/cpu.h @@ -32,4 +32,21 @@ struct arch_state_struct { #define VMX_MF_32 1 #define VMX_MF_64 2 +#define CPUID_LEAF_0x1 0x1 +#define CPUID_LEAF_0x4 0x4 +#define CPUID_LEAF_0x6 0x6 +#define CPUID_LEAF_0x9 0x9 +#define CPUID_LEAF_0xA 0xA +#define CPUID_LEAF_0x80000001 0x80000001 + +#define NUM_CORES_RESET_MASK 0x00003FFF +#define NUM_THREADS_RESET_MASK 0xFF00FFFF + +#define VMX_VCPU_CPUID_L1_ECX_RESERVED_18 0x00040000 +#define VMX_VCPU_CPUID_L1_ECX_RESERVED_6 0x00000040 + +#define VMX_VCPU_CPUID_L1_ECX_RESERVED \ + ( VMX_VCPU_CPUID_L1_ECX_RESERVED_18 | \ + VMX_VCPU_CPUID_L1_ECX_RESERVED_6 ) + #endif /* __ASM_X86_HVM_VMX_CPU_H__ */